#!/bin/bash

msg_icon=bunsen-face

# name of fortune file(s) to use
cookie=cbbl
debug=0
msg_time_default=20000
msg_time=0

# Improved algorithm:
# 1. a fixed delay
# 2. word_delay
# 3. char_delay
# (the final delay is added together from all these)
init_delay=2000
word_delay=250
char_delay=25

HELP="  bl-fortune is a script to display custom fortunes.

Usage:  bl-fortune [OPTIONS]

Options:
        -i <icon>, --icon=<icon>    use different icon
                                    Default is $msg_icon
        -w <time>, --word-delay=<time> set delay per word
                                    Default is ${word_delay}ms
                                    Overrides -t
        -c <time>, --char-delay=<time> set delay per character
                                    Default is ${char_delay}ms
                                    Overrides -t
        -d <time>, --init-delay=<time> set initial delay
                                    Default is ${init_delay}ms
                                    Overrides -t

        The options -w, -c and -d are cumulative, they add up to a final 
        message display time. This is the default mode of operation.
        It can be overridden with:

        -t <time>, --time=<time>    set fixed message expiry time in ms.
                                    If one of the options -w, -c or -d have been
                                    set incorrectly (0 or smaller), this is the 
                                    fallback value: ${msg_time_default}ms

        Mixing -w, -c, -d options with -t option can result in strange timing.

        -C <name>, --cookie='<name>[ name]'  set fortune cookie list(s)
                                    Default is $cookie
                                    This can contain multiple fortunes and
                                    options to fortune. Example:
                                    bl-fortune -C \"-e cbbl fortunes\"
                                    (enclose multiple words in quotes)
        -D                          Debug - enable some terminal messages
        -h, --help  show this message

Description:
        This is a wrapper around notify-send. The default behaviour is to choose
        a fortune from the 'cbbl' collection, which is gathered from CrunchBang
        and BunsenLabs forum posts, and display it for a time appropriate to the
        length of the quote, along with the obnoxious Beaker icon.
"

error_exit() {
    echo "$0 error: $1" >&2
    exit 1
}
# need to escape a few chars that make notify-send puke (because it defaults to pango markup)
escapes() {
    retval="${1//-/\\-}"
    retval="${retval//&/\&amp;}"
    retval="${retval//</\&lt;}"
    retval="${retval//>/\&gt;}"
    retval="${retval//\"/\&quot;}"
}

debug() {
    [[ "$debug" == 1 ]] && echo -e "$@"
}

while [[ -n $1 ]]
do
    case $1 in
    --help|-h)
        echo "$HELP"
        exit 0
        ;;
    -i)
        msg_icon="$2"
        shift 2
        ;;
    --icon=*)
        msg_icon="${1#--icon=}"
        shift
        ;;
    -t)
        msg_time="$2"
        init_delay=0
        word_delay=0
        char_delay=0
        shift 2
        ;;
    --time=*)
        msg_time="${1#--time=}"
        init_delay=0
        word_delay=0
        char_delay=0
        shift
        ;;
    -d)
        init_delay="$2"
        shift 2
        ;;
    --init-delay=*)
        init_delay="${1#--init-delay=}"
        shift
        ;;
    -w)
        word_delay="$2"
        shift 2
        ;;
    --word-delay=*)
        word_delay="${1#--word-delay=}"
        shift
        ;;
    -c)
        char_delay="$2"
        shift 2
        ;;
    --char-delay=*)
        char_delay="${1#--char-delay=}"
        shift
        ;;
    -D)
        debug=1
        shift 1
        ;;
    -C)
        cookie="$2"
        shift 2
        ;;
    --cookie=*)
        cookie="${1#--cookie=}"
        shift
        ;;
    *)
        error_exit "$1: no such option"
        ;;
    esac
done

text="$(fortune $cookie)"

# Improved algorithm:
# 1. an initial delay
# 2. word_delay
# 3. char_delay
# (the final delay (msg_time) is added together from all these)
if (( init_delay > 0 )) || (( word_delay > 0 )) || (( char_delay > 0 )); then
    debug "Calculate a text-based message time\ninit_delay: $init_delay\nword_delay: $word_delay\nchar_delay: $char_delay"
    words="$(wc -w <<<"$text")"
    chars="$(wc -m <<<"$text")"
    msg_time="$(( init_delay + (words * word_delay) + (chars * char_delay)))"
    (( msg_time <= 0 )) && debug "Invalid value for msg_time: $msg_time - using fixed message time" && msg_time=$msg_time_default
else
    debug "Fixed message time"
    (( msg_time <= 0 )) && msg_time=$msg_time_default
fi

debug "Timeout:  ${msg_time}ms"

header=( $text )
if (( "${#header[0]}" < 4 )) && (( "${#header[1]}" < 16 )); then
    header="${header[0]} ${header[1]}"
else
    header="${header[0]}"
fi

text="${text#$header}"
text="${text#$'\n'}"
text="${text# }"

escapes "$header"
header="$retval"
debug "Header:   $header"

escapes "$text"
text="$retval"
debug "Text:     $text"

notify-send --icon="$msg_icon" --expire-time="$msg_time" "$header" "$text"

exit
